package authoritah.db;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;

public class Event {
	private int id;
	private Timestamp start;
	private Timestamp end;
	private int maxPoints;
	private String name;
	private EventType eventType;
	
	/////////////////////////
	// Getters and Setters //
	/////////////////////////
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public Timestamp getStart() {
		return start;
	}
	public void setStart(Timestamp start) {
		this.start = start;
	}
	public Timestamp getEnd() {
		return end;
	}
	public void setEnd(Timestamp end) {
		this.end = end;
	}
	public int getMaxPoints() {
		return maxPoints;
	}
	public void setMaxPoints(int maxPoints) {
		this.maxPoints = maxPoints;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public EventType getEventType() {
		return eventType;
	}
	public void setEventType(EventType eventType) {
		this.eventType = eventType;
	}
	
	
	//////////////////////
	// Database methods //
	//////////////////////
	
	/** 
	 * Retrieves an event from the database file. If no event with supplied id exists, returns null.
	 * @param id
	 * @return
	 */
	public static Event getEvent(int id){
		Event event = new Event();
		try {
            ParityDB db = ParityDB.getInstance();
            
            Connection conn = db.getConn();
            
            PreparedStatement ps = conn.prepareStatement("SELECT * FROM event WHERE event_id=?");
            ps.setInt(1, id);
            ResultSet rs = ps.executeQuery();
            
            // Iterate the result set, printing each column
            while (rs.next()) {            	
                event.setId(rs.getInt("event_id"));
                event.setStart(new Timestamp(rs.getLong("start")));
                event.setEnd(new Timestamp(rs.getLong("end")));
                event.setMaxPoints(rs.getInt("max_points"));
                event.setEventType(EventType.getEventType(rs.getInt("type_id")));
                event.setName(rs.getString("name"));
            }            
            // Close the connection
            conn.close();
            
        }
        catch (Exception e) {
        	e.printStackTrace();
        }
        return event;
	}
	
	/** 
	 * Retrieves an event from the database file. If no event with supplied id exists, returns null.
	 * @param id
	 * @return
	 */
	public static Event getEvent(Timestamp start, Timestamp end){
		Event event = new Event();
		try {
            ParityDB db = ParityDB.getInstance();
            
            Connection conn = db.getConn();
            
            PreparedStatement ps = conn.prepareStatement("SELECT * FROM event WHERE start=? AND end=?");
            ps.setTimestamp(1, start);
            ps.setTimestamp(2, end);
            ResultSet rs = ps.executeQuery();
            
            // Iterate the result set, printing each column
            while (rs.next()) {            	
                event.setId(rs.getInt("event_id"));
                event.setStart(new Timestamp(rs.getLong("start")));
                event.setEnd(new Timestamp(rs.getLong("end")));
                event.setMaxPoints(rs.getInt("max_points"));
                event.setEventType(EventType.getEventType(rs.getInt("type_id")));
                event.setName(rs.getString("name"));
            }            
            // Close the connection
            conn.close();
            
        }
        catch (Exception e) {
        	e.printStackTrace();
        }
        return event;
	}
	
	/**
	 * Stores an event into the database.
	 * @param event
	 */
	public static void saveEvent(Event event){
		try {
			ParityDB db = ParityDB.getInstance();
            
            Connection conn = db.getConn();
            
            PreparedStatement ps = conn.prepareStatement("INSERT INTO event (start, end, max_points, type_id, name) VALUES (?, ?, ?, ?, ?)");
            ps.setLong(1, event.getStart().getTime());
            ps.setLong(2, event.getEnd().getTime());
            ps.setInt(3, event.getMaxPoints());
            ps.setInt(4, event.getEventType().getId());
            ps.setString(5, event.getName());
            ps.executeUpdate();
            
            // Close the connection
            conn.close();
        }
        catch (Exception e) {
        	e.printStackTrace();
        }
	}
	
	/**
	 * Retrieves all events in the database.
	 * @return All events currently in the database.
	 */
	public static Collection<Event> getAllEvents() {
		Collection<Event> events = new ArrayList<Event>();
		try {
			ParityDB db = ParityDB.getInstance();            
            Connection conn = db.getConn();
            
            PreparedStatement ps = conn.prepareStatement("SELECT * FROM event");
            ResultSet rs = ps.executeQuery();
            
            // Iterate the result set, adding to the collection.
            while (rs.next()) {
            	Event event = new Event();
                event.setId(rs.getInt("event_id"));
                event.setStart(new Timestamp(rs.getLong("start")));
                event.setEnd(new Timestamp(rs.getLong("end")));
                event.setMaxPoints(rs.getInt("max_points"));
                event.setEventType(EventType.getEventType(rs.getInt("type_id")));
                event.setName(rs.getString("name"));
                events.add(event);
            }
            
            // Close the connection
            conn.close();
            
        }
        catch (Exception e) {
        	e.printStackTrace();
        }
        return events;
	}
	
	public String toString() {
		return name;
	}
}
